home *** CD-ROM | disk | FTP | other *** search
/ SuperHack / SuperHack CD.bin / CODING / GRAPHICS / PNGLIB06.ZIP / PNGRUTIL.C < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-01  |  42.3 KB  |  1,519 lines

  1.  
  2. /* pngrutil.c - utilities to read a png file
  3.  
  4.    pnglib version 0.6
  5.    For conditions of distribution and use, see copyright notice in png.h
  6.    Copyright (c) 1995 Guy Eric Schalnat, Group 42, Inc.
  7.    May 1, 1995
  8.    */
  9.  
  10. #define PNG_INTERNAL
  11. #include "png.h"
  12.  
  13. /* grab an uint 32 from a buffer */
  14. png_uint_32
  15. png_get_uint_32(png_byte *buf)
  16. {
  17.    png_uint_32 i;
  18.  
  19.    i = ((png_uint_32)(*buf) << 24) +
  20.       ((png_uint_32)(*(buf + 1)) << 16) +
  21.       ((png_uint_32)(*(buf + 2)) << 8) +
  22.       (png_uint_32)(*(buf + 3));
  23.  
  24.    return i;
  25. }
  26.  
  27. /* grab an uint 16 from a buffer */
  28. png_uint_16
  29. png_get_uint_16(png_byte *buf)
  30. {
  31.    png_uint_16 i;
  32.  
  33.    i = ((png_uint_16)(*buf) << 8) +
  34.       (png_uint_16)(*(buf + 1));
  35.  
  36.    return i;
  37. }
  38.  
  39. /* read data, and run it through the crc */
  40. void
  41. png_crc_read(png_struct *png_ptr, png_byte *buf, png_uint_32 length)
  42. {
  43.    png_read_data(png_ptr, buf, length);
  44.    png_calculate_crc(png_ptr, buf, length);
  45. }
  46.  
  47. /* skip data, but calcuate the crc anyway */
  48. void
  49. png_crc_skip(png_struct *png_ptr, png_uint_32 length)
  50. {
  51.    png_uint_32 i;
  52.  
  53.    for (i = length; i > png_ptr->zbuf_size; i -= png_ptr->zbuf_size)
  54.    {
  55.       png_read_data(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
  56.       png_calculate_crc(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
  57.    }
  58.    if (i)
  59.    {
  60.       png_read_data(png_ptr, png_ptr->zbuf, i);
  61.       png_calculate_crc(png_ptr, png_ptr->zbuf, i);
  62.    }
  63. }
  64.  
  65. /* read and check the IDHR chunk */
  66. void
  67. png_handle_IHDR(png_struct *png_ptr, png_info *info, png_uint_32 length)
  68. {
  69.    png_byte buf[13];
  70.    png_uint_32 width, height;
  71.    int bit_depth, color_type, compression_type, filter_type;
  72.    int interlace_type;
  73.  
  74.    /* check the length */
  75.    if (length != 13)
  76.       png_error(png_ptr, "Invalid IHDR chunk");
  77.  
  78.    png_crc_read(png_ptr, buf, 13);
  79.  
  80.    width = png_get_uint_32(buf);
  81.    height = png_get_uint_32(buf + 4);
  82.    bit_depth = buf[8];
  83.    color_type = buf[9];
  84.    compression_type = buf[10];
  85.    filter_type = buf[11];
  86.    interlace_type = buf[12];
  87.  
  88.    /* check for width and height valid values */
  89.    if (width == 0 || height == 0 ||
  90.       width > 0xffffffffL || height > 0xffffffffL)
  91.       png_error(png_ptr, "Invalid Width or Height Found");
  92.  
  93.    /* check other values */
  94.    if (bit_depth != 1 && bit_depth != 2 &&
  95.       bit_depth != 4 && bit_depth != 8 &&
  96.       bit_depth != 16)
  97.       png_error(png_ptr, "Invalid Bit Depth Found");
  98.  
  99.    if (color_type < 0 || color_type == 1 ||
  100.       color_type == 5 || color_type > 6)
  101.       png_error(png_ptr, "Invalid Color Type Found");
  102.  
  103.    if (color_type == PNG_COLOR_TYPE_PALETTE &&
  104.       bit_depth == 16)
  105.       png_error(png_ptr, "Found Invalid Color Type and Bit Depth Combination");
  106.  
  107.    if ((color_type == PNG_COLOR_TYPE_RGB ||
  108.       color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
  109.       color_type == PNG_COLOR_TYPE_RGB_ALPHA) &&
  110.       bit_depth < 8)
  111.       png_error(png_ptr, "Found Invalid Color Type and Bit Depth Combination");
  112.  
  113.    if (interlace_type > 1)
  114.       png_error(png_ptr, "Found Invalid Interlace Value");
  115.  
  116.    if (compression_type > 0)
  117.       png_error(png_ptr, "Found Invalid Compression Value");
  118.  
  119.    if (filter_type > 0)
  120.       png_error(png_ptr, "Found Invalid Filter Value");
  121.  
  122.    /* set internal variables */
  123.    png_ptr->width = width;
  124.    png_ptr->height = height;
  125.    png_ptr->bit_depth = bit_depth;
  126.    png_ptr->interlaced = interlace_type;
  127.    png_ptr->color_type = color_type;
  128.  
  129.    /* find number of channels */
  130.    switch (png_ptr->color_type)
  131.    {
  132.       case 0:
  133.       case 3:
  134.          png_ptr->channels = 1;
  135.          break;
  136.       case 2:
  137.          png_ptr->channels = 3;
  138.          break;
  139.       case 4:
  140.          png_ptr->channels = 2;
  141.          break;
  142.       case 6:
  143.          png_ptr->channels = 4;
  144.          break;
  145.    }
  146.    /* set up other useful info */
  147.    png_ptr->pixel_depth = png_ptr->bit_depth *
  148.       png_ptr->channels;
  149.    png_ptr->rowbytes = ((png_ptr->width *
  150.       (png_uint_32)png_ptr->pixel_depth + 7) >> 3);
  151.    /* call the IHDR callback (which should just set up info) */
  152.    png_read_IHDR(png_ptr, info, width, height, bit_depth,
  153.       color_type, compression_type, filter_type, interlace_type);
  154. }
  155.  
  156. /* read and check the palette */
  157. void
  158. png_handle_PLTE(png_struct *png_ptr, png_info *info, png_uint_32 length)
  159. {
  160.    int num, i;
  161.    png_color *palette;
  162.  
  163.    if (length % 3)
  164.       png_error(png_ptr, "Invalid Palette Chunk");
  165.  
  166.    num = (int)length / 3;
  167.    palette = (png_color *)png_malloc(png_ptr, num * sizeof (png_color));
  168.    for (i = 0; i < num; i++)
  169.    {
  170.       png_byte buf[3];
  171.  
  172.       png_crc_read(png_ptr, buf, 3);
  173.       /* don't depend upon png_color being any order */
  174.       palette[i].red = buf[0];
  175.       palette[i].green = buf[1];
  176.       palette[i].blue = buf[2];
  177.    }
  178.    png_ptr->palette = palette;
  179.    png_ptr->num_palette = num;
  180.    png_read_PLTE(png_ptr, info, palette, num);
  181. }
  182.  
  183. void
  184. png_handle_gAMA(png_struct *png_ptr, png_info *info, png_uint_32 length)
  185. {
  186.    png_uint_32 igamma;
  187.    float gamma;
  188.    png_byte buf[4];
  189.  
  190.    if (length != 4)
  191.    {
  192.       png_crc_skip(png_ptr, length);
  193.       return;
  194.    }
  195.  
  196.    png_crc_read(png_ptr, buf, 4);
  197.    igamma = png_get_uint_32(buf);
  198.    /* check for zero gamma */
  199.    if (!igamma)
  200.       return;
  201.  
  202.    gamma = (float)igamma / (float)100000.0;
  203.    png_read_gAMA(png_ptr, info, gamma);
  204.    png_ptr->gamma = gamma;
  205. }
  206.  
  207. void
  208. png_handle_sBIT(png_struct *png_ptr, png_info *info, png_uint_32 length)
  209. {
  210.    int slen;
  211.    png_byte buf[4];
  212.  
  213.    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  214.       slen = 3;
  215.    else
  216.       slen = png_ptr->channels;
  217.  
  218.    if (length != (png_uint_32)slen)
  219.    {
  220.       png_crc_skip(png_ptr, length);
  221.       return;
  222.    }
  223.  
  224.    png_crc_read(png_ptr, buf, length);
  225.    if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
  226.    {
  227.       png_ptr->sig_bit.red = buf[0];
  228.       png_ptr->sig_bit.green = buf[1];
  229.       png_ptr->sig_bit.blue = buf[2];
  230.       png_ptr->sig_bit.alpha = buf[3];
  231.    }
  232.    else
  233.    {
  234.       png_ptr->sig_bit.gray = buf[0];
  235.       png_ptr->sig_bit.alpha = buf[1];
  236.    }
  237.    png_read_sBIT(png_ptr, info, &(png_ptr->sig_bit));
  238. }
  239.  
  240. void
  241. png_handle_cHRM(png_struct *png_ptr, png_info *info, png_uint_32 length)
  242. {
  243.    png_byte buf[4];
  244.    png_uint_32 v;
  245.    float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
  246.  
  247.    if (length != 32)
  248.    {
  249.       png_crc_skip(png_ptr, length);
  250.       return;
  251.    }
  252.  
  253.    png_crc_read(png_ptr, buf, 4);
  254.    v = png_get_uint_32(buf);
  255.    white_x = (float)v / (float)100000.0;
  256.  
  257.    png_crc_read(png_ptr, buf, 4);
  258.    v = png_get_uint_32(buf);
  259.    white_y = (float)v / (float)100000.0;
  260.  
  261.    png_crc_read(png_ptr, buf, 4);
  262.    v = png_get_uint_32(buf);
  263.    red_x = (float)v / (float)100000.0;
  264.  
  265.    png_crc_read(png_ptr, buf, 4);
  266.    v = png_get_uint_32(buf);
  267.    red_y = (float)v / (float)100000.0;
  268.  
  269.    png_crc_read(png_ptr, buf, 4);
  270.    v = png_get_uint_32(buf);
  271.    green_x = (float)v / (float)100000.0;
  272.  
  273.    png_crc_read(png_ptr, buf, 4);
  274.    v = png_get_uint_32(buf);
  275.    green_y = (float)v / (float)100000.0;
  276.  
  277.    png_crc_read(png_ptr, buf, 4);
  278.    v = png_get_uint_32(buf);
  279.    blue_x = (float)v / (float)100000.0;
  280.  
  281.    png_crc_read(png_ptr, buf, 4);
  282.    v = png_get_uint_32(buf);
  283.    blue_y = (float)v / (float)100000.0;
  284.  
  285.    png_read_cHRM(png_ptr, info,
  286.       white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
  287. }
  288.  
  289. void
  290. png_handle_tRNS(png_struct *png_ptr, png_info *info, png_uint_32 length)
  291. {
  292.    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  293.    {
  294.       if (length > png_ptr->num_palette)
  295.       {
  296.          png_crc_skip(png_ptr, length);
  297.          return;
  298.       }
  299.  
  300.       png_ptr->trans = png_malloc(png_ptr, length);
  301.       png_crc_read(png_ptr, png_ptr->trans, length);
  302.       png_ptr->num_trans = (int)length;
  303.    }
  304.    else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
  305.    {
  306.       png_byte buf[6];
  307.  
  308.       if (length != 6)
  309.       {
  310.          png_crc_skip(png_ptr, length);
  311.          return;
  312.       }
  313.  
  314.       png_crc_read(png_ptr, buf, length);
  315.       png_ptr->num_trans = 3;
  316.       png_ptr->trans_values.red = png_get_uint_16(buf);
  317.       png_ptr->trans_values.green = png_get_uint_16(buf + 2);
  318.       png_ptr->trans_values.blue = png_get_uint_16(buf + 4);
  319.    }
  320.    else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
  321.    {
  322.       png_byte buf[6];
  323.  
  324.       if (length != 2)
  325.       {
  326.          png_crc_skip(png_ptr, length);
  327.          return;
  328.       }
  329.  
  330.       png_crc_read(png_ptr, buf, 2);
  331.       png_ptr->num_trans = 1;
  332.       png_ptr->trans_values.gray = png_get_uint_16(buf);
  333.    }
  334.    else
  335.       png_error(png_ptr, "Invalid tRNS chunk");
  336.  
  337.    png_read_tRNS(png_ptr, info, png_ptr->trans, png_ptr->num_trans,
  338.       &(png_ptr->trans_values));
  339. }
  340.  
  341. void
  342. png_handle_bKGD(png_struct *png_ptr, png_info *info, png_uint_32 length)
  343. {
  344.    int truelen;
  345.    png_byte buf[6];
  346.  
  347.    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  348.       truelen = 1;
  349.    else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
  350.       truelen = 6;
  351.    else
  352.       truelen = 2;
  353.  
  354.    if (length != (png_uint_32)truelen)
  355.    {
  356.       png_crc_skip(png_ptr, length);
  357.       return;
  358.    }
  359.  
  360.    png_crc_read(png_ptr, buf, length);
  361.    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  362.       png_ptr->background.index = buf[0];
  363.    else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
  364.       png_ptr->background.gray = png_get_uint_16(buf);
  365.    else
  366.    {
  367.       png_ptr->background.red = png_get_uint_16(buf);
  368.       png_ptr->background.green = png_get_uint_16(buf + 2);
  369.       png_ptr->background.blue = png_get_uint_16(buf + 4);
  370.    }
  371.  
  372.    png_read_bKGD(png_ptr, info, &(png_ptr->background));
  373. }
  374.  
  375. void
  376. png_handle_hIST(png_struct *png_ptr, png_info *info, png_uint_32 length)
  377. {
  378.    int num, i;
  379.  
  380.    if (length != 2 * png_ptr->num_palette)
  381.    {
  382.       png_crc_skip(png_ptr, length);
  383.       return;
  384.    }
  385.  
  386.    num = (int)length / 2;
  387.    png_ptr->hist = png_malloc(png_ptr, num * sizeof (png_uint_16));
  388.    for (i = 0; i < num; i++)
  389.    {
  390.       png_byte buf[2];
  391.  
  392.       png_crc_read(png_ptr, buf, 2);
  393.       png_ptr->hist[i] = png_get_uint_16(buf);
  394.    }
  395.    png_read_hIST(png_ptr, info, png_ptr->hist);
  396. }
  397.  
  398. void
  399. png_handle_pHYs(png_struct *png_ptr, png_info *info, png_uint_32 length)
  400. {
  401.    png_byte buf[9];
  402.    png_uint_32 res_x, res_y;
  403.    int unit_type;
  404.  
  405.    if (length != 9)
  406.    {
  407.       png_crc_skip(png_ptr, length);
  408.       return;
  409.    }
  410.  
  411.    png_crc_read(png_ptr, buf, 9);
  412.  
  413.    res_x = png_get_uint_32(buf);
  414.    res_y = png_get_uint_32(buf + 4);
  415.    unit_type = buf[8];
  416.    png_read_pHYs(png_ptr, info, res_x, res_y, unit_type);
  417. }
  418.  
  419. void
  420. png_handle_oFFs(png_struct *png_ptr, png_info *info, png_uint_32 length)
  421. {
  422.    png_byte buf[9];
  423.    png_uint_32 offset_x, offset_y;
  424.    int unit_type;
  425.  
  426.    if (length != 9)
  427.    {
  428.       png_crc_skip(png_ptr, length);
  429.       return;
  430.    }
  431.  
  432.    png_crc_read(png_ptr, buf, 9);
  433.  
  434.    offset_x = png_get_uint_32(buf);
  435.    offset_y = png_get_uint_32(buf + 4);
  436.    unit_type = buf[8];
  437.    png_read_oFFs(png_ptr, info, offset_x, offset_y, unit_type);
  438. }
  439.  
  440. void
  441. png_handle_tIME(png_struct *png_ptr, png_info *info, png_uint_32 length)
  442. {
  443.    png_byte buf[7];
  444.    png_time mod_time;
  445.  
  446.    if (length != 7)
  447.    {
  448.       png_crc_skip(png_ptr, length);
  449.       return;
  450.    }
  451.  
  452.    png_crc_read(png_ptr, buf, 7);
  453.  
  454.    mod_time.second = buf[6];
  455.    mod_time.minute = buf[5];
  456.    mod_time.hour = buf[4];
  457.    mod_time.day = buf[3];
  458.    mod_time.month = buf[2];
  459.    mod_time.year = png_get_uint_16(buf);
  460.  
  461.    png_read_tIME(png_ptr, info, &mod_time);
  462. }
  463.  
  464. /* note: this does not correctly handle chunks that are > 64K */
  465. void
  466. png_handle_tEXt(png_struct *png_ptr, png_info *info, png_uint_32 length)
  467. {
  468.    char *key, *text;
  469.  
  470.    key = text = NULL;
  471.  
  472.    key = (char *)png_large_malloc(png_ptr, length + 1);
  473.    png_crc_read(png_ptr, (png_byte *)key, length);
  474.    key[(png_size_t)length] = '\0';
  475.  
  476.    for (text = key; *text; text++)
  477.       /* empty loop */ ;
  478.  
  479.    if (text == key + (png_size_t)length)
  480.    {
  481.       png_large_free(png_ptr, key);
  482.       return;
  483.    }
  484.  
  485.    text++;
  486.  
  487.    png_read_tEXt(png_ptr, info, key, text, length - (text - key));
  488. }
  489.  
  490. /* note: this does not correctly handle chunks that are > 64K compressed */
  491. void
  492. png_handle_zTXt(png_struct *png_ptr, png_info *info, png_uint_32 length)
  493. {
  494.    char *key, *text;
  495.    int ret;
  496.    png_uint_32 text_size, key_size;
  497.  
  498.    key = text = NULL;
  499.  
  500.    key = png_large_malloc(png_ptr, length + 1);
  501.    png_crc_read(png_ptr, (png_byte *)key, length);
  502.    key[(png_size_t)length] = '\0';
  503.  
  504.    for (text = key; *text; text++)
  505.       /* empty loop */ ;
  506.  
  507.    if (text == key + (png_size_t)length)
  508.    {
  509.       png_large_free(png_ptr, key);
  510.       return;
  511.    }
  512.  
  513.    text++;
  514.  
  515.    if (*text) /* check compression byte */
  516.    {
  517.       png_large_free(png_ptr, key);
  518.       return;
  519.    }
  520.  
  521.    png_ptr->zstream->next_in = (png_byte *)text;
  522.    png_ptr->zstream->avail_in = (uInt)(length - (text - key));
  523.    png_ptr->zstream->next_out = png_ptr->zbuf;
  524.    png_ptr->zstream->avail_out = (png_size_t)png_ptr->zbuf_size;
  525.  
  526.    key_size = text - key;
  527.    text_size = 0;
  528.    text = NULL;
  529.  
  530.    while (png_ptr->zstream->avail_in)
  531.    {
  532.       ret = inflate(png_ptr->zstream, Z_PARTIAL_FLUSH);
  533.       if (ret != Z_OK && ret != Z_STREAM_END)
  534.       {
  535.          inflateReset(png_ptr->zstream);
  536.          png_large_free(png_ptr, key);
  537.          png_large_free(png_ptr, text);
  538.          return;
  539.       }
  540.       if (!png_ptr->zstream->avail_out || ret == Z_STREAM_END)
  541.       {
  542.          if (!text)
  543.          {
  544.             text = png_malloc(png_ptr,
  545.                png_ptr->zbuf_size - png_ptr->zstream->avail_out +
  546.                   key_size);
  547.             memcpy(text + (png_size_t)key_size, png_ptr->zbuf,
  548.                (png_size_t)(png_ptr->zbuf_size - png_ptr->zstream->avail_out));
  549.             memcpy(text, key, (png_size_t)key_size);
  550.             text_size = key_size + (png_size_t)png_ptr->zbuf_size -
  551.                png_ptr->zstream->avail_out;
  552.          }
  553.          else
  554.          {
  555.             char *tmp;
  556.  
  557.             tmp = text;
  558.             text = png_large_malloc(png_ptr, text_size +
  559.                png_ptr->zbuf_size - png_ptr->zstream->avail_out);
  560.             memcpy(text, tmp, (png_size_t)text_size);
  561.             png_large_free(png_ptr, tmp);
  562.             memcpy(text + (png_size_t)text_size, png_ptr->zbuf,
  563.                (png_size_t)(png_ptr->zbuf_size - png_ptr->zstream->avail_out));
  564.             text_size += png_ptr->zbuf_size - png_ptr->zstream->avail_out;
  565.          }
  566.          if (ret != Z_STREAM_END)
  567.          {
  568.             png_ptr->zstream->next_out = png_ptr->zbuf;
  569.             png_ptr->zstream->avail_out = (uInt)png_ptr->zbuf_size;
  570.          }
  571.       }
  572.       else
  573.       {
  574.          break;
  575.       }
  576.  
  577.       if (ret == Z_STREAM_END)
  578.          break;
  579.    }
  580.  
  581.    inflateReset(png_ptr->zstream);
  582.  
  583.    if (ret != Z_STREAM_END)
  584.    {
  585.       png_large_free(png_ptr, key);
  586.       png_large_free(png_ptr, text);
  587.       return;
  588.    }
  589.  
  590.    png_large_free(png_ptr, key);
  591.    key = text;
  592.    text += (png_size_t)key_size;
  593.  
  594.    png_read_zTXt(png_ptr, info, key, text, text_size, 0);
  595. }
  596.  
  597. /* Combines the row recently read in with the previous row.
  598.    This routine takes care of alpha and transparency if requested.
  599.    This routine also handles the two methods of progressive display
  600.    of interlaced images, depending on the mask value.
  601.    The mask value describes which pixels are to be combined with
  602.    the row.  The pattern always repeats every 8 pixels, so just 8
  603.    bits are needed.  A one indicates the pixels is to be combined,
  604.    a zero indicates the pixel is to be skipped.  This is in addition
  605.    to any alpha or transparency value associated with the pixel.  If
  606.    you want all pixels to be combined, pass 0xff (255) in mask.
  607. */
  608. void png_combine_row(png_struct *png_ptr, png_byte *row,
  609.    png_byte *ref, int mask)
  610. {
  611.    if ((png_ptr->transformations & PNG_ALPHA) && !ref)
  612.       png_error(png_ptr, "NULL reference row");
  613.  
  614.    if (!(png_ptr->transformations & PNG_ALPHA) && mask == 0xff)
  615.    {
  616.       memcpy(row, png_ptr->row_buf + 1,
  617.          (png_size_t)((png_ptr->width *
  618.          png_ptr->row_info.pixel_depth + 7) >> 3));
  619.    }
  620.    else if (!(png_ptr->transformations & PNG_ALPHA))
  621.    {
  622.       switch (png_ptr->row_info.pixel_depth)
  623.       {
  624.          case 1:
  625.          {
  626.             png_byte *sp;
  627.             png_byte *dp;
  628.             int m;
  629.             int shift;
  630.             png_uint_32 i;
  631.             int value;
  632.  
  633.             sp = png_ptr->row_buf + 1;
  634.             dp = row;
  635.             shift = 7;
  636.             m = 0x80;
  637.             for (i = 0; i < png_ptr->width; i++)
  638.             {
  639.                if (m & mask)
  640.                {
  641.                   value = (*sp >> shift) & 0x1;
  642.                   *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
  643.                   *dp |= (value << shift);
  644.                }
  645.  
  646.                if (shift == 0)
  647.                {
  648.                   shift = 7;
  649.                   sp++;
  650.                   dp++;
  651.                }
  652.                else
  653.                   shift--;
  654.  
  655.                if (m == 1)
  656.                   m = 0x80;
  657.                else
  658.                   m >>= 1;
  659.             }
  660.             break;
  661.          }
  662.          case 2:
  663.          {
  664.             png_byte *sp;
  665.             png_byte *dp;
  666.             int m;
  667.             int shift;
  668.             png_uint_32 i;
  669.             int value;
  670.  
  671.             sp = png_ptr->row_buf + 1;
  672.             dp = row;
  673.             shift = 6;
  674.             m = 0x80;
  675.             for (i = 0; i < png_ptr->width; i++)
  676.             {
  677.                if (m & mask)
  678.                {
  679.                   value = (*sp >> shift) & 0x3;
  680.                   *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
  681.                   *dp |= (value << shift);
  682.                }
  683.  
  684.                if (shift == 0)
  685.                {
  686.                   shift = 6;
  687.                   sp++;
  688.                   dp++;
  689.                }
  690.                else
  691.                   shift -= 2;
  692.                if (m == 1)
  693.                   m = 0x80;
  694.                else
  695.                   m >>= 1;
  696.             }
  697.             break;
  698.          }
  699.          case 4:
  700.          {
  701.             png_byte *sp;
  702.             png_byte *dp;
  703.             int m;
  704.             int shift;
  705.             png_uint_32 i;
  706.             int value;
  707.  
  708.             sp = png_ptr->row_buf + 1;
  709.             dp = row;
  710.             shift = 6;
  711.             m = 0x80;
  712.             for (i = 0; i < png_ptr->width; i++)
  713.             {
  714.                if (m & mask)
  715.                {
  716.                   value = (*sp >> shift) & 0xf;
  717.                   *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
  718.                   *dp |= (value << shift);
  719.                }
  720.  
  721.                if (shift == 0)
  722.                {
  723.                   shift = 4;
  724.                   sp++;
  725.                   dp++;
  726.                }
  727.                else
  728.                   shift -= 4;
  729.                if (m == 1)
  730.                   m = 0x80;
  731.                else
  732.                   m >>= 1;
  733.             }
  734.             break;
  735.          }
  736.          default:
  737.          {
  738.             png_byte *sp;
  739.             png_byte *dp;
  740.             png_uint_32 i;
  741.             int pixel_bytes, m;
  742.  
  743.             pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
  744.  
  745.             sp = png_ptr->row_buf + 1;
  746.             dp = row;
  747.             m = 0x80;
  748.             for (i = 0; i < png_ptr->width; i++)
  749.             {
  750.                if (m & mask)
  751.                {
  752.                   memcpy(dp, sp, pixel_bytes);
  753.                }
  754.  
  755.                sp += pixel_bytes;
  756.                dp += pixel_bytes;
  757.  
  758.                if (m == 1)
  759.                   m = 0x80;
  760.                else
  761.                   m >>= 1;
  762.             }
  763.             break;
  764.          }
  765.       }
  766.    }
  767.    else /* (png_ptr->transformations & PNG_ALPHA) */
  768.    {
  769. #ifdef work_in_progress
  770.       switch (png_ptr->row_info.pixel_depth)
  771.       {
  772.          case 1:
  773.          {
  774.             png_byte *sp;
  775.             png_byte *dp;
  776.             png_byte *rp;
  777.             int m;
  778.             int shift;
  779.             png_uint_32 i;
  780.             int value;
  781.  
  782.             sp = png_ptr->row_buf + 1;
  783.             dp = row;
  784.             rp = ref;
  785.             shift = 7;
  786.             m = 0x80;
  787.             for (i = 0; i < png_ptr->width; i++)
  788.             {
  789.                if (m & mask)
  790.                {
  791.                   value = (*sp >> shift) & 0x1;
  792.                   if ((png_ptr->row_info.color_type !=
  793.                      PNG_COLOR_TYPE_PALETTE &&
  794.                      png_ptr->trans_values.gray == value) ||
  795.                      (png_ptr->row_info.color_type ==
  796.                      PNG_COLOR_TYPE_PALETTE &&
  797.                      (png_ptr->num_trans >= value ||
  798.                      png_ptr->trans[value] < 255)))
  799.                   {
  800.                      value = (*rp >> shift) & 0x1;
  801.                   }
  802.                   *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
  803.                   *dp |= (value << shift);
  804.                }
  805.  
  806.                if (shift == 0)
  807.                {
  808.                   shift = 7;
  809.                   sp++;
  810.                   dp++;
  811.                   rp++;
  812.                }
  813.                else
  814.                   shift--;
  815.  
  816.                if (m == 1)
  817.                   m = 0x80;
  818.                else
  819.                   m >>= 1;
  820.             }
  821.             break;
  822.          }
  823.          case 2:
  824.          {
  825.             png_byte *sp;
  826.             png_byte *dp;
  827.             png_byte *rp;
  828.             int m;
  829.             int shift;
  830.             png_uint_32 i;
  831.             int value;
  832.  
  833.             sp = png_ptr->row_buf + 1;
  834.             dp = row;
  835.             rp = ref;
  836.             shift = 6;
  837.             m = 0x80;
  838.             for (i = 0; i < png_ptr->width; i++)
  839.             {
  840.                if (m & mask)
  841.                {
  842.                   value = (*sp >> shift) & 0x3;
  843.                   if ((png_ptr->row_info.color_type !=
  844.                      PNG_COLOR_TYPE_PALETTE &&
  845.                      png_ptr->trans_values.gray == value) ||
  846.                      (png_ptr->row_info.color_type ==
  847.                      PNG_COLOR_TYPE_PALETTE &&
  848.                      (png_ptr->num_trans >= value ||
  849.                      png_ptr->trans[value] < 255)))
  850.                   {
  851.                      value = (*rp >> shift) & 0x3;
  852.                   }
  853.                   *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
  854.                   *dp |= (value << shift);
  855.                }
  856.  
  857.                if (shift == 0)
  858.                {
  859.                   shift = 6;
  860.                   sp++;
  861.                   dp++;
  862.                   rp++;
  863.                }
  864.                else
  865.                   shift -= 2;
  866.                if (m == 1)
  867.                   m = 0x80;
  868.                else
  869.                   m >>= 1;
  870.             }
  871.             break;
  872.          }
  873.          case 4:
  874.          {
  875.             png_byte *sp;
  876.             png_byte *dp;
  877.             png_byte *rp;
  878.             int m;
  879.             int shift;
  880.             png_uint_32 i;
  881.             int value;
  882.  
  883.             sp = png_ptr->row_buf + 1;
  884.             dp = row;
  885.             rp = ref;
  886.             shift = 6;
  887.             m = 0x80;
  888.             for (i = 0; i < png_ptr->width; i++)
  889.             {
  890.                if (m & mask)
  891.                {
  892.                   value = (*sp >> shift) & 0xf;
  893.                   if ((png_ptr->row_info.color_type !=
  894.                      PNG_COLOR_TYPE_PALETTE &&
  895.                      png_ptr->trans_values.gray == value) ||
  896.                      (png_ptr->row_info.color_type ==
  897.                      PNG_COLOR_TYPE_PALETTE &&
  898.                      (png_ptr->num_trans >= value ||
  899.                      png_ptr->trans[value] < 255)))
  900.                   {
  901.                      value = (*rp >> shift) & 0xf;
  902.                   }
  903.                   *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
  904.                   *dp |= (value << shift);
  905.                }
  906.  
  907.                if (shift == 0)
  908.                {
  909.                   shift = 4;
  910.                   sp++;
  911.                   dp++;
  912.                   rp++;
  913.                }
  914.                else
  915.                   shift -= 4;
  916.                if (m == 1)
  917.                   m = 0x80;
  918.                else
  919.                   m >>= 1;
  920.             }
  921.             break;
  922.          }
  923.          default:
  924.          {
  925.             png_byte *sp;
  926.             png_byte *dp;
  927.             png_byte *rp;
  928.             png_uint_32 i;
  929.             int pixel_bytes, m;
  930.  
  931.             pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
  932.  
  933.             sp = png_ptr->row_buf + 1;
  934.             dp = row;
  935.             rp = ref;
  936.             m = 0x80;
  937.             for (i = 0; i < png_ptr->width; i++)
  938.             {
  939.                if (m & mask)
  940.                {
  941.                   if (png_ptr->row_info.color_type ==
  942.                      PNG_COLOR_TYPE_RGB_ALPHA &&
  943.                      png_ptr->row_info.bit_depth == 8)
  944.                   {
  945.                      int j;
  946.                      png_uint_16 a;
  947.                      png_byte *sp2, *dp2, *rp2;
  948.  
  949.                      a = *(sp + 3);
  950.                      for (j = 0, sp2 = sp, dp2 = dp, rp2 = rp;
  951.                         j < 3;
  952.                         j++, sp2++, dp2++, rp2++)
  953.                      {
  954.                         *dp2 = ((png_uint_16)(*sp2) * a +
  955.                            (png_uint_16)(*rp2) * (255U - a) +
  956.                            127U) / 255U;
  957.                      }
  958.                   }
  959.                   else if (png_ptr->row_info.color_type ==
  960.                      PNG_COLOR_TYPE_RGB_ALPHA &&
  961.                      png_ptr->row_info.bit_depth == 16)
  962.                   {
  963.                      int j;
  964.                      png_uint_32 a;
  965.                      png_byte *sp2, *dp2, *rp2;
  966.  
  967.                      a = ((png_uint_32)(*(sp + 6)) << 8) +
  968.                         (png_uint_32)(*(sp + 7));
  969.                      for (j = 0, sp2 = sp, dp2 = dp, rp2 = rp;
  970.                         j < 3;
  971.                         j++, sp2 += 2, dp2 += 2, rp2 += 2)
  972.                      {
  973.                         png_uint_32 sv, dv;
  974.  
  975.                         sv = ((png_uint_32)(*sp2) << 8) +
  976.                            (png_uint_32)(*(sp2 + 1));
  977.                         dv = ((png_uint_32)(*rp2) << 8) +
  978.                            (png_uint_32)(*(rp2 + 1));
  979.                         dv = (sv * a + dv * (65535U - a) +
  980.                            32767U) / 65535U;
  981.                         *dp2 = (dv >> 8) & 0xff;
  982.                         *(dp2 + 1) = dv & 0xff;
  983.                      }
  984.                   }
  985.                   else if (png_ptr->row_info.color_type ==
  986.                      PNG_COLOR_TYPE_GRAY_ALPHA &&
  987.                      png_ptr->row_info.bit_depth == 8)
  988.                   {
  989.                      *dp = ((png_uint_16)(*sp) *
  990.                         (png_uint_16)(*(sp + 1)) +
  991.                         (png_uint_16)(*rp) *
  992.                         (255U - (png_uint_16)(*(sp + 1))) +
  993.                         127U) / 255U;
  994.                   }
  995.                   else if (png_ptr->row_info.color_type ==
  996.                      PNG_COLOR_TYPE_GRAY_ALPHA &&
  997.                      png_ptr->row_info.bit_depth == 16)
  998.                   {
  999.                      png_uint_32 a, sv, dv;
  1000.  
  1001.                      a = ((png_uint_32)(*(sp + 2)) << 8) +
  1002.                         (png_uint_32)(*(sp + 3));
  1003.                      sv = ((png_uint_32)(*sp) << 8) +
  1004.                         (png_uint_32)(*(sp + 1));
  1005.                      dv = ((png_uint_32)(*rp) << 8) +
  1006.                         (png_uint_32)(*(rp + 1));
  1007.                      dv = (sv * a + dv * (65535U - a) +
  1008.                         32767U) / 65535U;
  1009.                      *dp = (dv >> 8) & 0xff;
  1010.                      *(dp + 1) = dv & 0xff;
  1011.                   }
  1012.                   else if (png_ptr->row_info.color_type ==
  1013.                      PNG_COLOR_TYPE_PALETTE)
  1014.                   {
  1015.                      if (*sp >= png_ptr->num_trans ||
  1016.                         png_ptr->trans[*sp] == 255)
  1017.                         *dp = *sp;
  1018.                      else
  1019.                         *dp = *rp;
  1020.                   }
  1021.                   else if   (png_ptr->row_info.color_type ==
  1022.                      PNG_COLOR_TYPE_GRAY &&
  1023.                      png_ptr->row_info.bit_depth == 8)
  1024.                   {
  1025.                      if (png_ptr->trans_values.gray ==
  1026.                         (png_uint_16)(*sp))
  1027.                         *dp = *rp;
  1028.                      else
  1029.                         *dp = *sp;
  1030.                   }
  1031.                   else if   (png_ptr->row_info.color_type ==
  1032.                      PNG_COLOR_TYPE_GRAY &&
  1033.                      png_ptr->row_info.bit_depth == 16)
  1034.                   {
  1035.                      if (png_ptr->trans_values.gray ==
  1036.                      ((png_uint_16)*sp << 8) +
  1037.                      (png_uint_16)*(sp + 1))
  1038.                      {
  1039.                         *dp = *rp;
  1040.                         *(dp + 1) = *(rp + 1);
  1041.                      }
  1042.                      else
  1043.                      {
  1044.                         *dp = *sp;
  1045.                         *(dp + 1) = *(sp + 1);
  1046.                      }
  1047.                   }
  1048.                   else if   (png_ptr->row_info.color_type ==
  1049.                      PNG_COLOR_TYPE_RGB &&
  1050.                      png_ptr->row_info.bit_depth == 8)
  1051.                   {
  1052.                      if (png_ptr->trans_values.red ==
  1053.                         (png_uint_16)sp[0] &&
  1054.                         png_ptr->trans_values.green ==
  1055.                         (png_uint_16)sp[1] &&
  1056.                         png_ptr->trans_values.blue ==
  1057.                         (png_uint_16)sp[2])
  1058.                      {
  1059.                         memcpy(dp, rp, 3);
  1060.                      }
  1061.                      else
  1062.                      {
  1063.                         memcpy(dp, sp, 3);
  1064.                      }
  1065.                   }
  1066.                   else if   (png_ptr->row_info.color_type ==
  1067.                      PNG_COLOR_TYPE_RGB &&
  1068.                      png_ptr->row_info.bit_depth == 16)
  1069.                   {
  1070.                      if (png_ptr->trans_values.red ==
  1071.                         ((png_uint_16)sp[0] << 8) +
  1072.                         (png_uint_16)sp[1] &&
  1073.                         png_ptr->trans_values.green ==
  1074.                         ((png_uint_16)sp[2] << 8) +
  1075.                         (png_uint_16)sp[3] &&
  1076.                         png_ptr->trans_values.blue ==
  1077.                         ((png_uint_16)sp[4] << 8) +
  1078.                         (png_uint_16)sp[5])
  1079.                      {
  1080.                         memcpy(dp, rp, 6);
  1081.                      }
  1082.                      else
  1083.                      {
  1084.                         memcpy(dp, sp, 6);
  1085.                      }
  1086.                   }
  1087.                }
  1088.  
  1089.                sp += pixel_bytes;
  1090.                dp += pixel_bytes;
  1091.                rp += pixel_bytes;
  1092.  
  1093.                if (m == 1)
  1094.                   m = 0x80;
  1095.                else
  1096.                   m >>= 1;
  1097.             }
  1098.             break;
  1099.          }
  1100.       }
  1101. #endif
  1102.    }
  1103. }
  1104.  
  1105. void
  1106. png_do_read_interlace(png_row_info *row_info, png_byte *row, int pass)
  1107. {
  1108.    if (row && row_info)
  1109.    {
  1110.       png_uint_32 final_width;
  1111.  
  1112.       final_width = row_info->width * png_pass_inc[pass];
  1113.  
  1114.       switch (row_info->pixel_depth)
  1115.       {
  1116.          case 1:
  1117.          {
  1118.             png_byte *sp, *dp;
  1119.             int sshift, dshift;
  1120.             png_byte v;
  1121.             png_uint_32 i;
  1122.             int j;
  1123.  
  1124.             sp = row + (png_size_t)((row_info->width - 1) >> 3);
  1125.             sshift = 7 - (int)((row_info->width + 7) & 7);
  1126.             dp = row + (png_size_t)((final_width - 1) >> 3);
  1127.             dshift = 7 - (int)((final_width + 7) & 7);
  1128.             for (i = row_info->width; i; i--)
  1129.             {
  1130.                v = (*sp >> sshift) & 0x1;
  1131.                for (j = 0; j < png_pass_inc[pass]; j++)
  1132.                {
  1133.                   *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff);
  1134.                   *dp |= (png_byte)(v << dshift);
  1135.                   if (dshift == 7)
  1136.                   {
  1137.                      dshift = 0;
  1138.                      dp--;
  1139.                   }
  1140.                   else
  1141.                      dshift++;
  1142.                }
  1143.                if (sshift == 7)
  1144.                {
  1145.                   sshift = 0;
  1146.                   sp--;
  1147.                }
  1148.                else
  1149.                   sshift++;
  1150.             }
  1151.             break;
  1152.          }
  1153.          case 2:
  1154.          {
  1155.             png_byte *sp, *dp;
  1156.             int sshift, dshift;
  1157.             png_byte v;
  1158.             png_uint_32 i, j;
  1159.  
  1160.             sp = row + (png_size_t)((row_info->width - 1) >> 2);
  1161.             sshift = (png_size_t)((3 - ((row_info->width + 3) & 3)) << 1);
  1162.             dp = row + (png_size_t)((final_width - 1) >> 2);
  1163.             dshift = (png_size_t)((3 - ((final_width + 3) & 3)) << 1);
  1164.             for (i = row_info->width; i; i--)
  1165.             {
  1166.                v = (*sp >> sshift) & 0x3;
  1167.                for (j = 0; j < png_pass_inc[pass]; j++)
  1168.                {
  1169.                   *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff);
  1170.                   *dp |= (v << dshift);
  1171.                   if (dshift == 6)
  1172.                   {
  1173.                      dshift = 0;
  1174.                      dp--;
  1175.                   }
  1176.                   else
  1177.                      dshift += 2;
  1178.                }
  1179.                if (sshift == 6)
  1180.                {
  1181.                   sshift = 0;
  1182.                   sp--;
  1183.                }
  1184.                else
  1185.                   sshift += 2;
  1186.             }
  1187.             break;
  1188.          }
  1189.          case 4:
  1190.          {
  1191.             png_byte *sp, *dp;
  1192.             int sshift, dshift;
  1193.             png_byte v;
  1194.             png_uint_32 i;
  1195.             int j;
  1196.  
  1197.             sp = row + (png_size_t)((row_info->width - 1) >> 1);
  1198.             sshift = (png_size_t)((1 - ((row_info->width + 1) & 1)) << 2);
  1199.             dp = row + (png_size_t)((final_width - 1) >> 1);
  1200.             dshift = (png_size_t)((1 - ((final_width + 1) & 1)) << 2);
  1201.             for (i = row_info->width; i; i--)
  1202.             {
  1203.                v = (*sp >> sshift) & 0xf;
  1204.                for (j = 0; j < png_pass_inc[pass]; j++)
  1205.                {
  1206.                   *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff);
  1207.                   *dp |= (v << dshift);
  1208.                   if (dshift == 4)
  1209.                   {
  1210.                      dshift = 0;
  1211.                      dp--;
  1212.                   }
  1213.                   else
  1214.                      dshift = 4;
  1215.                }
  1216.                if (sshift == 4)
  1217.                {
  1218.                   sshift = 0;
  1219.                   sp--;
  1220.                }
  1221.                else
  1222.                   sshift = 4;
  1223.             }
  1224.             break;
  1225.          }
  1226.          default:
  1227.          {
  1228.             png_byte *sp, *dp;
  1229.             png_byte v[8];
  1230.             png_uint_32 i;
  1231.             int j;
  1232.             int pixel_bytes;
  1233.  
  1234.             pixel_bytes = (row_info->pixel_depth >> 3);
  1235.  
  1236.             sp = row + (png_size_t)((row_info->width - 1) * pixel_bytes);
  1237.             dp = row + (png_size_t)((final_width - 1) * pixel_bytes);
  1238.             for (i = row_info->width; i; i--)
  1239.             {
  1240.                memcpy(v, sp, pixel_bytes);
  1241.                for (j = 0; j < png_pass_inc[pass]; j++)
  1242.                {
  1243.                   memcpy(dp, v, pixel_bytes);
  1244.                   dp -= pixel_bytes;
  1245.                }
  1246.                sp -= pixel_bytes;
  1247.             }
  1248.             break;
  1249.          }
  1250.       }
  1251.       row_info->width = final_width;
  1252.       row_info->rowbytes = ((final_width *
  1253.          (png_uint_32)row_info->pixel_depth + 7) >> 3);
  1254.    }
  1255. }
  1256.  
  1257. void
  1258. png_read_filter_row(png_row_info *row_info, png_byte *row,
  1259.    png_byte *prev_row, int filter)
  1260. {
  1261.    switch (filter)
  1262.    {
  1263.       case 0:
  1264.          break;
  1265.       case 1:
  1266.       {
  1267.          png_uint_32 i;
  1268.          int bpp;
  1269.          png_byte *rp;
  1270.          png_byte *lp;
  1271.  
  1272.          bpp = (row_info->pixel_depth + 7) / 8;
  1273.          for (i = (png_uint_32)bpp, rp = row + bpp, lp = row;
  1274.             i < row_info->rowbytes; i++, rp++, lp++)
  1275.          {
  1276.             *rp = (png_byte)(((int)(*rp) + (int)(*lp)) & 0xff);
  1277.          }
  1278.          break;
  1279.       }
  1280.       case 2:
  1281.       {
  1282.          png_uint_32 i;
  1283.          png_byte *rp;
  1284.          png_byte *pp;
  1285.  
  1286.          for (i = 0, rp = row, pp = prev_row;
  1287.             i < row_info->rowbytes; i++, rp++, pp++)
  1288.          {
  1289.             *rp = (png_byte)(((int)(*rp) + (int)(*pp)) & 0xff);
  1290.          }
  1291.          break;
  1292.       }
  1293.       case 3:
  1294.       {
  1295.          png_uint_32 i;
  1296.          int bpp;
  1297.          png_byte *rp;
  1298.          png_byte *pp;
  1299.          png_byte *lp;
  1300.  
  1301.          bpp = (row_info->pixel_depth + 7) / 8;
  1302.          for (i = 0, rp = row, pp = prev_row;
  1303.             i < (png_uint_32)bpp; i++, rp++, pp++)
  1304.          {
  1305.             *rp = (png_byte)(((int)(*rp) +
  1306.                ((int)(*pp) / 2)) & 0xff);
  1307.          }
  1308.          for (lp = row; i < row_info->rowbytes; i++, rp++, lp++, pp++)
  1309.          {
  1310.             *rp = (png_byte)(((int)(*rp) +
  1311.                (int)(*pp + *lp) / 2) & 0xff);
  1312.          }
  1313.          break;
  1314.       }
  1315.       case 4:
  1316.       {
  1317.          int bpp;
  1318.          png_uint_32 i;
  1319.          png_byte *rp;
  1320.          png_byte *pp;
  1321.          png_byte *lp;
  1322.          png_byte *cp;
  1323.  
  1324.          bpp = (row_info->pixel_depth + 7) / 8;
  1325.          for (i = 0, rp = row, pp = prev_row,
  1326.             lp = row - bpp, cp = prev_row - bpp;
  1327.             i < row_info->rowbytes; i++, rp++, pp++, lp++, cp++)
  1328.          {
  1329.             int a, b, c, pa, pb, pc, p;
  1330.  
  1331.             b = *pp;
  1332.             if (i >= (png_uint_32)bpp)
  1333.             {
  1334.                c = *cp;
  1335.                a = *lp;
  1336.             }
  1337.             else
  1338.             {
  1339.                a = c = 0;
  1340.             }
  1341.             p = a + b - c;
  1342.             pa = abs(p - a);
  1343.             pb = abs(p - b);
  1344.             pc = abs(p - c);
  1345.  
  1346.             if (pa <= pb && pa <= pc)
  1347.                p = a;
  1348.             else if (pb <= pc)
  1349.                p = b;
  1350.             else
  1351.                p = c;
  1352.  
  1353.             *rp = (png_byte)(((int)(*rp) + p) & 0xff);
  1354.          }
  1355.          break;
  1356.       }
  1357.       default:
  1358.          break;
  1359.    }
  1360. }
  1361.  
  1362. void png_read_finish_row(png_struct *png_ptr)
  1363. {
  1364.    png_ptr->row_number++;
  1365.    if (png_ptr->row_number < png_ptr->num_rows)
  1366.       return;
  1367.  
  1368.    if (png_ptr->interlaced)
  1369.    {
  1370.       png_ptr->row_number = 0;
  1371.       memset(png_ptr->prev_row, 0, (png_size_t)png_ptr->rowbytes + 1);
  1372.       do
  1373.       {
  1374.          png_ptr->pass++;
  1375.          if (png_ptr->pass >= 7)
  1376.             break;
  1377.          png_ptr->iwidth = (png_ptr->width +
  1378.             png_pass_inc[png_ptr->pass] - 1 -
  1379.             png_pass_start[png_ptr->pass]) /
  1380.             png_pass_inc[png_ptr->pass];
  1381.          png_ptr->irowbytes = ((png_ptr->iwidth *
  1382.             png_ptr->pixel_depth + 7) >> 3) + 1;
  1383.          if (!(png_ptr->transformations & PNG_INTERLACE))
  1384.          {
  1385.             png_ptr->num_rows = (png_ptr->height +
  1386.                png_pass_yinc[png_ptr->pass] - 1 -
  1387.                png_pass_ystart[png_ptr->pass]) /
  1388.                png_pass_yinc[png_ptr->pass];
  1389.             if (!(png_ptr->num_rows))
  1390.                continue;
  1391.          }
  1392.       } while (png_ptr->iwidth == 0);
  1393.  
  1394.       if (png_ptr->pass < 7)
  1395.          return;
  1396.    }
  1397.  
  1398.    if (png_ptr->idat_size || png_ptr->zstream->avail_in)
  1399.       png_error(png_ptr, "Extra compression data");
  1400.  
  1401.    inflateReset(png_ptr->zstream);
  1402.  
  1403.    png_ptr->mode = PNG_AT_LAST_IDAT;
  1404. }
  1405.  
  1406. void png_read_start_row(png_struct *png_ptr)
  1407. {
  1408.    int max_pixel_depth;
  1409.    png_uint_32 rowbytes;
  1410.  
  1411.    if (png_ptr->interlaced)
  1412.    {
  1413.       if (!(png_ptr->transformations & PNG_INTERLACE))
  1414.          png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
  1415.             png_pass_ystart[0]) / png_pass_yinc[0];
  1416.       else
  1417.          png_ptr->num_rows = png_ptr->height;
  1418.  
  1419.       png_ptr->iwidth = (png_ptr->width +
  1420.          png_pass_inc[png_ptr->pass] - 1 -
  1421.          png_pass_start[png_ptr->pass]) /
  1422.          png_pass_inc[png_ptr->pass];
  1423.       png_ptr->irowbytes = ((png_ptr->iwidth *
  1424.          png_ptr->pixel_depth + 7) >> 3) + 1;
  1425.    }
  1426.    else
  1427.    {
  1428.       png_ptr->num_rows = png_ptr->height;
  1429.       png_ptr->iwidth = png_ptr->width;
  1430.       png_ptr->irowbytes = png_ptr->rowbytes + 1;
  1431.    }
  1432.  
  1433.    max_pixel_depth = png_ptr->pixel_depth;
  1434.  
  1435.    if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8)
  1436.    {
  1437.       max_pixel_depth = 8;
  1438.    }
  1439.  
  1440.    if (png_ptr->transformations & (PNG_EXPAND || PNG_PACK))
  1441.    {
  1442.       if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  1443.       {
  1444.          if (png_ptr->num_trans)
  1445.             max_pixel_depth = 32;
  1446.          else
  1447.             max_pixel_depth = 24;
  1448.       }
  1449.       else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
  1450.       {
  1451.          if (max_pixel_depth < 8)
  1452.             max_pixel_depth = 8;
  1453.          if (png_ptr->num_trans)
  1454.             max_pixel_depth *= 2;
  1455.       }
  1456.       else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
  1457.       {
  1458.          if (png_ptr->num_trans)
  1459.          {
  1460.             max_pixel_depth *= 4;
  1461.             max_pixel_depth /= 3;
  1462.          }
  1463.       }
  1464.    }
  1465.  
  1466.    if (png_ptr->transformations & PNG_RGBA)
  1467.    {
  1468.       if (max_pixel_depth < 32)
  1469.          max_pixel_depth = 32;
  1470.    }
  1471.  
  1472.    if (png_ptr->transformations & PNG_GRAY_TO_RGB)
  1473.    {
  1474.       if ((png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) ||
  1475.          png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
  1476.       {
  1477.          if (max_pixel_depth <= 16)
  1478.             max_pixel_depth = 32;
  1479.          else if (max_pixel_depth <= 32)
  1480.             max_pixel_depth = 64;
  1481.       }
  1482.       else
  1483.       {
  1484.          if (max_pixel_depth <= 8)
  1485.             max_pixel_depth = 24;
  1486.          else if (max_pixel_depth <= 16)
  1487.             max_pixel_depth = 48;
  1488.       }
  1489.    }
  1490.  
  1491.    /* align the width on the next larger 8 pixels.  Mainly used
  1492.       for interlacing */
  1493.    rowbytes = ((png_ptr->width + 7) & ~((png_uint_32)7));
  1494.    /* calculate the maximum bytes needed, adding a byte and a pixel
  1495.       for safety sake */
  1496.    rowbytes = ((rowbytes * (png_uint_32)max_pixel_depth + 7) >> 3) +
  1497.       1 + ((max_pixel_depth + 7) >> 3);
  1498. #ifdef PNG_MAX_MALLOC_64K
  1499.    if (rowbytes > 65536L)
  1500.       png_error(png_ptr, "This image requires a row greater then 64KB");
  1501. #endif
  1502.    png_ptr->row_buf = (png_byte *)png_large_malloc(png_ptr, rowbytes);
  1503.  
  1504. #ifdef PNG_MAX_MALLOC_64K
  1505.    if (png_ptr->rowbytes + 1 > 65536L)
  1506.       png_error(png_ptr, "This image requires a row greater then 64KB");
  1507. #endif
  1508.    png_ptr->prev_row = png_large_malloc(png_ptr,
  1509.       png_ptr->rowbytes + 1);
  1510.  
  1511.    memset(png_ptr->prev_row, 0, (png_size_t)png_ptr->rowbytes + 1);
  1512.  
  1513.    png_ptr->row_init = 1;
  1514.  
  1515.    /* if we have to do any modifications of values for the transformations,
  1516.       do them here */
  1517. }
  1518.  
  1519.